package com.ingenio.siot.adapter;

import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import com.ingenio.siot.Adapter;
import com.ingenio.siot.entity.Criterio;
import com.ingenio.siot.entity.CriterioIntervalo;
import com.ingenio.siot.entity.Estado;
import com.ingenio.siot.entity.EstadoTransito;
import com.ingenio.siot.entity.Transito;
import com.mysql.jdbc.CallableStatement;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;

public class EstadosTransitoAdapter extends Adapter{
	
	public void calcularEstado(){
		TransitoAdapter ta = new TransitoAdapter();
		CriterioAdapter ca = new CriterioAdapter();
		EstadoAdapter ea = new EstadoAdapter();
		EstadosTransitoAdapter eta = new EstadosTransitoAdapter();
		Connection conn = null;
    	PreparedStatement stmt = null;
		try {
			List<Transito> transitoPendiente = ta.devolverTransitoPendiente();
			List<Criterio> criterios = ca.devolverTodos();
			List<CriterioIntervalo> intervalos = new ArrayList<CriterioIntervalo>();
			conn = (Connection) abrirConexion();
			for (Transito transito : transitoPendiente) {
				for (Criterio criterio : criterios) {
					intervalos = null;
					String formula = criterio.getFormula();
					// calcular formula
					String queryFormula ="SELECT "+formula+" FROM transitos WHERE IdLinea = ? and fechaEstado = ?";
		    		stmt = (PreparedStatement) conn.prepareStatement(queryFormula);
		    		stmt.setInt(1, transito.getLinea().getIdLinea());
		    		stmt.setTimestamp(2, new Timestamp(transito.getFechaEstado().getTime()));
		    		ResultSet result = stmt.executeQuery();
		    		
		    		if(result.next()){
		    			Double resultadoFor = result.getDouble(1);
		    			Estado estado = null;
		    			intervalos = criterio.getIntervalos();
		    			for (CriterioIntervalo ci : intervalos){
		    				// busco el estado segun el intervalo en que se encuentra el valor de la formula
		    				switch (ci.getTipoIntervalo().getIdTipoIntervalo()) {
								case 1: // mayor 
									if (resultadoFor > ci.getValorMinimo()){
										estado = ci.getEstado();
									}
									break;
								case 2: // menor 
									if (resultadoFor < ci.getValorMaximo()){
										estado = ci.getEstado();
									}
									break;	
								case 3: // between
									if (resultadoFor >= ci.getValorMinimo() && resultadoFor <= ci.getValorMaximo()){
										estado = ci.getEstado();
									}
									break;		
							}
		    				if (estado != null){
		    					break;
		    				}
		    			}
		    			if (estado == null){
		    				// si no le asigno ningun estado, pongo por defecto estado indeterminado
		    				estado = ea.devolverEstado(5);
		    			}
		    			// inserto estado en tabla estadostransito
		    			eta.insertarEstadoTransito(transito, criterio, estado,resultadoFor);
		    		}
				}
			}
			// cambio marca de procesado 
			ta.actualizarTransitoPendiente(transitoPendiente);
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			cerrarConexion(conn);
		}	
	}
	
	public void insertarEstadoTransito(Transito transito, Criterio criterio, Estado estado, Double valorFunc) throws Exception{
		Connection conn = null;
		PreparedStatement stmt = null;
		try {
    		conn = (Connection) abrirConexion();
    		String query ="INSERT INTO estadostransito(IdCriterio, IdLinea, fechaEstado, IdEstado, valorFuncion) VALUES(?,?,?,?,?)";
    		stmt = (PreparedStatement) conn.prepareStatement(query);
    		stmt.setInt(1, criterio.getIdCriterio());
    		stmt.setInt(2, transito.getLinea().getIdLinea());
    		stmt.setTimestamp(3, new Timestamp(transito.getFechaEstado().getTime()));
    		stmt.setInt(4, estado.getIdEstado());
    		stmt.setDouble(5, valorFunc);
    		stmt.execute();
		}
		catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		cerrarConexion(conn);
    	}
	}
	
	public List<EstadoTransito> devolverEstadosTrantido(Criterio criterio) {
		Connection conn = null;
		CallableStatement callableStatement = null;
		String storeProc = "{call EstadoTransito(?)}";
		List<EstadoTransito> estadosTransito = new ArrayList<EstadoTransito>();
		TransitoAdapter ta = new TransitoAdapter();
		EstadoAdapter ea = new EstadoAdapter();
    	try {
			conn = (Connection) abrirConexion();
			callableStatement = (CallableStatement) conn.prepareCall(storeProc);
			callableStatement.setInt(1, criterio.getIdCriterio());
			ResultSet rs = callableStatement.executeQuery();
			EstadoTransito et = null;
			while(rs.next()) {
				Integer idLinea = rs.getInt("IdLinea");
				Integer idEstado = rs.getInt("IdEstado");
				Timestamp fechaEstado = rs.getTimestamp("fechaEstado");
				Double valorFuncion = rs.getDouble("valorFuncion");
				Estado estado = ea.devolverEstado(idEstado, conn);
				Transito transito = ta.devolverTransito(idLinea, fechaEstado, conn);
				et = new EstadoTransito(transito, criterio, estado,valorFuncion);
				estadosTransito.add(et);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
    	return estadosTransito;
	}
	
	
	public static void main(String args[]) throws Exception {
		
		EstadosTransitoAdapter eta = new EstadosTransitoAdapter();		
		eta.calcularEstado();
 	}
	
}
